package com.zhentao.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.cart.CartFeignClient;
import com.zhentao.dto.h5.OrderInfoDto;
import com.zhentao.entity.h5.CartInfo;
import com.zhentao.entity.order.OrderInfo;
import com.zhentao.entity.order.OrderItem;
import com.zhentao.entity.order.OrderLog;
import com.zhentao.entity.product.ProductSku;
import com.zhentao.entity.user.UserAddress;
import com.zhentao.entity.user.UserInfo;
import com.zhentao.mapper.OrderInfoMapper;
import com.zhentao.mapper.OrderItemMapper;
import com.zhentao.mapper.OrderLogMapper;
import com.zhentao.product.ProductFeignClient;
import com.zhentao.service.OrderInfoService;
import com.zhentao.user.UserFeignClient;
import com.zhentao.utils.AuthContextUtil;
import com.zhentao.vo.common.ResultCodeEnum;
import com.zhentao.vo.common.ZhentaoException;
import com.zhentao.vo.h5.TradeVo;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import java.util.*;

@Service
public class OrderInfoServiceImpl implements OrderInfoService {
    @Resource
    private CartFeignClient cartFeignClient;
    @Resource
    private ProductFeignClient productFeignClient;

    @Resource
    private UserFeignClient userFeignClient;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private OrderLogMapper orderLogMapper;
    @Resource
    private RedisTemplate<String,String> redisTemplate;
    /**
     * 确定下单
     * @return
     */
    @Override
    public TradeVo getTrade() {
        // 获取当前登录的用户的id
//        Long userId = AuthContextUtil.getUserInfo().getId();
        // 获取选中的购物项列表数据
        List<CartInfo> cartInfoList = cartFeignClient.getAllCkecked() ;
        List<OrderItem> orderItemList = new ArrayList<>();
        for (CartInfo cartInfo : cartInfoList) {        // 将购物项数据转换成功订单明细数据
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(cartInfo.getSkuId());
            orderItem.setSkuName(cartInfo.getSkuName());
            orderItem.setSkuNum(cartInfo.getSkuNum());
            orderItem.setSkuPrice(cartInfo.getCartPrice());
            orderItem.setThumbImg(cartInfo.getImgUrl());
            orderItemList.add(orderItem);
        }

        // 计算总金额
        BigDecimal totalAmount = new BigDecimal(0);
        for(OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTotalAmount(totalAmount);
        tradeVo.setOrderItemList(orderItemList);
        return tradeVo;
    }
    /**
     * 提交订单
     * @param orderInfoDto
     * @return
     */
    @Override
    @Transactional
    public Long submitOrder(OrderInfoDto orderInfoDto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String userInfoJSON = redisTemplate.opsForValue().get("user:ztzx:" + token);
        AuthContextUtil.setUserInfo(JSON.parseObject(userInfoJSON , UserInfo.class));
        // 数据校验
        List<OrderItem> orderItemList = orderInfoDto.getOrderItemList();
        if (CollectionUtils.isEmpty(orderItemList)) {
            throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
        }

        for (OrderItem orderItem : orderItemList) {
            ProductSku productSku = productFeignClient.getBySkuId(orderItem.getSkuId());
            if(null == productSku) {
                throw new ZhentaoException(ResultCodeEnum.DATA_ERROR);
            }
            //校验库存
            if(orderItem.getSkuNum().intValue() > productSku.getStockNum().intValue()) {
                throw new ZhentaoException(ResultCodeEnum.STOCK_LESS);
            }
        }

        // 构建订单数据，保存订单

        Long id = AuthContextUtil.getUserInfo().getId();
        String nickName = AuthContextUtil.getUserInfo().getNickName();
        System.out.println(id);
        OrderInfo orderInfo = new OrderInfo();
        //订单编号
        orderInfo.setOrderNo(String.valueOf(System.currentTimeMillis()));
        //用户id
        orderInfo.setUserId(id);
        //用户昵称
        orderInfo.setNickName(nickName);
        //用户收货地址信息
        UserAddress userAddress = userFeignClient.getUserAddress(orderInfoDto.getUserAddressId());
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverAddress(userAddress.getFullAddress());
        //订单金额
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalAmount);
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setOriginalTotalAmount(totalAmount);
        orderInfo.setFeightFee(orderInfoDto.getFeightFee());
        orderInfo.setPayType(2);
        orderInfo.setOrderStatus(0);
        orderInfoMapper.save(orderInfo);

        //保存订单明细
        for (OrderItem orderItem : orderItemList) {
            orderItem.setOrderId(orderInfo.getId());
            orderItemMapper.save(orderItem);
        }

        //记录日志
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(0);
        orderLog.setNote("提交订单");
        orderLogMapper.save(orderLog);

        // TODO 远程调用service-cart微服务接口清空购物车数据
        // 5、清空购物车数据
        cartFeignClient.deleteChecked() ;
        // 6、返回订单id
        return orderInfo.getId();
    }
    /**
     * 获取订单信息
     * @param orderId
     * @return
     */
    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }
    /**
     * 立即购买
     * @param skuId
     * @return
     */
    @Override
    public TradeVo buy(Long skuId) {
        // 查询商品
        ProductSku productSku = productFeignClient.getBySkuId(skuId);
        List<OrderItem> orderItemList = new ArrayList<>();
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setSkuNum(1);
        orderItem.setSkuPrice(productSku.getSalePrice());
        orderItem.setThumbImg(productSku.getThumbImg());
        orderItemList.add(orderItem);

        // 计算总金额
        BigDecimal totalAmount = productSku.getSalePrice();
        TradeVo tradeVo = new TradeVo();
        tradeVo.setTotalAmount(totalAmount);
        tradeVo.setOrderItemList(orderItemList);

        // 返回
        return tradeVo;
    }
    /**
     * 获取订单分页列表
     * @param page
     * @param limit
     * @param orderStatus
     * @return
     */
    @Override
    public Map<String, Object> findUserPage(Integer page, Integer limit, Integer orderStatus) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String userInfoJSON = redisTemplate.opsForValue().get("user:ztzx:" + token);
        AuthContextUtil.setUserInfo(JSON.parseObject(userInfoJSON , UserInfo.class));
        Map<String,Object> map = new HashMap<>();
        Page<OrderInfo> page1 = new Page<>(page, limit);
        Long userId = AuthContextUtil.getUserInfo().getId();
        Page<OrderInfo> orderInfoPage = orderInfoMapper.findUserPage(page1,userId, orderStatus);
        List<OrderInfo> orderInfoList = orderInfoPage.getRecords();
        orderInfoList.forEach(orderInfo -> {
            List<OrderItem> orderItem = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId,orderInfo.getId()).eq(OrderItem::getIsDeleted,0).orderByDesc(OrderItem::getId));
            orderInfo.setOrderItemList(orderItem);
        });
        map.put("list",orderInfoList);
        map.put("total",orderInfoPage.getTotal());
        return map;
    }
    /**
     * 获取订单信息
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getByOrderNo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.selectOne(Wrappers.<OrderInfo>lambdaQuery().eq(OrderInfo::getOrderNo,orderNo));
        List<OrderItem> orderItem = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId,orderInfo.getId()));
        orderInfo.setOrderItemList(orderItem);
        return orderInfo;
    }
    /**
     * 获取订单分页列表
     * @param orderNo
     * @param orderStatus
     * @return
     */
    @Transactional
    @Override
    public void updateOrderStatus(String orderNo, Integer orderStatus) {

        // 更新订单状态
        OrderInfo orderInfo = orderInfoMapper.selectOne(Wrappers.<OrderInfo>lambdaQuery().eq(OrderInfo::getOrderNo,orderNo));
        orderInfo.setOrderStatus(1);
        orderInfo.setPayType(orderStatus);
        orderInfo.setPaymentTime(new Date());
        orderInfo.setUpdateTime(new Date());
        orderInfoMapper.updateById(orderInfo);

        // 记录日志
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(1);
        orderLog.setNote("支付宝支付成功");
        orderLogMapper.save(orderLog);
    }
}